extern "C"
{
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "luajit.h"
}

//#include "libs/flip/flip.hpp"
#include "libs/gvl/sockets.hpp"
//#include "libs/psync/psync.hpp"
//#include "libs/box2d/box2d.hpp"
//#include "libs/portaudio/portaudio.hpp"

#include "libs/test.hpp"

#include <gvl/io/common_bitstream.hpp>
#include <gvl/math/ieee.hpp>
#include <ctime>

static void openlib(lua_State* L, char const* name, lua_CFunction func)
{
	lua_pushcfunction(L, func);
    lua_pushstring(L, name);
    lua_call(L, 1, 0);
}

int test();

void report_error(lua_State* L)
{
	printf("Error: %s", lua_tostring(L, -1));
	lua_pop(L, 1);
	abort();
}

void checked_dofile(lua_State* L, char const* file)
{
	if(luaL_dofile(L, file))
	{
		report_error(L);
	}
}

int main(int argc, char* argv[])
{
	gvl_init_ieee();

	lua_State* L = luaL_newstate();

	// TODO for Win/x86: luaJIT_setmode(L, idx, LUAJIT_MODE_WRAPCFUNC|LUAJIT_MODE_ON)
	
	luaL_openlibs(L);
	openlib(L, "flip", luaopen_flip);
	openlib(L, "sockets", luaopen_sockets);
	openlib(L, "psync", luaopen_psync);
	openlib(L, "box2d", luaopen_box2d);
	openlib(L, "serialize", luaopen_serialize);
	openlib(L, "portaudio", luaopen_portaudio);
	openlib(L, "filesystem", luaopen_filesystem);
	openlib(L, "random", luaopen_random);
	openlib(L, "system", luaopen_system);
	

	openlib(L, "test", luaopen_test);

	checked_dofile(L, "box2d.lua");
	checked_dofile(L, "flip.lua");
	checked_dofile(L, "psync.lua");

	luaL_loadfile(L, "test.lua");

	lua_createtable(L, argc, 0);
	for(int i = 0; i < argc; ++i)
	{
		lua_pushstring(L, argv[i]);
		lua_rawseti(L, -2, i);
	}
	
	if(lua_pcall(L, 1, LUA_MULTRET, 0))
		report_error(L);

	lua_close(L);
}